***************************************************************************/
static void
-ggv_bin_read_bytes(QFile& file, QByteArray& buf, qint64 size, const char* descr = NULL)
+ggv_bin_read_bytes(QDataStream& stream, QByteArray& buf, qint64 len, const char* descr = NULL)
{
- if (size > file.size())
- fatal(MYNAME ": Read size error (%s)\n", descr ? descr : "");
- buf = file.read(size);
- if (buf.size() < size)
+ buf.resize(len);
+ if (stream.readRawData(buf.data(), len) != len || stream.status() != QDataStream::Ok)
fatal(MYNAME ": Read error (%s)\n", descr ? descr : "");
}
static quint16
-ggv_bin_read16(QFile& file, const char* descr = NULL)
+ggv_bin_read16(QDataStream& stream, const char* descr = NULL)
{
- QByteArray buf;
quint16 res;
-
- ggv_bin_read_bytes(file, buf, 2, descr);
- res = qFromLittleEndian<quint16>((const uchar*)buf.constData());
+ stream >> res;
+ if (stream.status() != QDataStream::Ok)
+ fatal(MYNAME ": Read error (%s)\n", descr ? descr : "");
if (global_opts.debug_level > 1)
qDebug("ovl: %-15s %5u (0x%04x)", descr, res, res);
return res;
}
static quint32
-ggv_bin_read32(QFile& file, const char* descr = NULL)
+ggv_bin_read32(QDataStream& stream, const char* descr = NULL)
{
- QByteArray buf;
quint32 res;
-
- ggv_bin_read_bytes(file, buf, 4, descr);
- res = qFromLittleEndian<quint32>((const uchar*)buf.constData());
+ stream >> res;
+ if (stream.status() != QDataStream::Ok)
+ fatal(MYNAME ": Read error (%s)\n", descr ? descr : "");
if (global_opts.debug_level > 1) {
if ((res & 0xFFFF0000) == 0)
qDebug("ovl: %-15s %5u (0x%08x)", descr, res, res);
}
static void
-ggv_bin_read_text16(QFile& file, QByteArray& buf, const char* descr = NULL)
+ggv_bin_read_text16(QDataStream& stream, QByteArray& buf, const char* descr = NULL)
{
- quint16 len;
-
- len = ggv_bin_read16(file, descr);
- ggv_bin_read_bytes(file, buf, len, descr);
+ quint16 len = ggv_bin_read16(stream, descr);
+ ggv_bin_read_bytes(stream, buf, len, descr);
buf[len] = 0;
if (global_opts.debug_level > 1)
qDebug() << "ovl: text =" << QString::fromLatin1(buf.constData()).simplified();
}
static void
-ggv_bin_read_text32(QFile& file, QByteArray& buf, const char* descr = NULL)
+ggv_bin_read_text32(QDataStream& stream, QByteArray& buf, const char* descr = NULL)
{
- quint32 len;
-
- len = ggv_bin_read32(file, descr);
- ggv_bin_read_bytes(file, buf, len, descr);
+ quint32 len = ggv_bin_read32(stream, descr);
+ ggv_bin_read_bytes(stream, buf, len, descr);
buf[len] = 0;
if (global_opts.debug_level > 1)
qDebug() << "ovl: text =" << QString::fromLatin1(buf.constData()).simplified();
}
static double
-ggv_bin_read_double(QFile& file, const char* descr = NULL)
+ggv_bin_read_double(QDataStream& stream, const char* descr = NULL)
{
- QByteArray buf;
- quint64 tmp;
- const double *res;
-
- ggv_bin_read_bytes(file, buf, sizeof(double), descr);
- tmp = qFromLittleEndian<quint64>((const uchar*)buf.constData());
- res = reinterpret_cast<const double*>(&tmp);
- return *res;
+ double res;
+ stream >> res;
+ if (stream.status() != QDataStream::Ok)
+ fatal(MYNAME ": Read error (%s)\n", descr ? descr : "");
+ return res;
}
/***************************************************************************
***************************************************************************/
static void
-ggv_bin_read_v2(QFile& file)
+ggv_bin_read_v2(QDataStream& stream)
{
QByteArray buf;
QString track_name;
quint64 entry_pos;
// header length is usually either 0x90 or 0x00
- header_len = ggv_bin_read16(file, "map name len");
+ header_len = ggv_bin_read16(stream, "map name len");
if (header_len > 0) {
- ggv_bin_read_bytes(file, buf, header_len, "map name");
+ ggv_bin_read_bytes(stream, buf, header_len, "map name");
buf.remove(0,4);
buf.append('\0');
if (global_opts.debug_level > 1)
qDebug() << "ovl: name =" << buf.constData();
}
- while (!file.atEnd()) {
+ while (!stream.atEnd()) {
track_name.clear();
if (global_opts.debug_level > 1)
- qDebug("------------------------------------ 0x%llx", file.pos());
+ qDebug("------------------------------------ 0x%llx", stream.device()->pos());
- entry_pos = file.pos();
- entry_type = ggv_bin_read16(file, "entry type");
- ggv_bin_read16(file, "entry group");
- ggv_bin_read16(file, "entry zoom");
- entry_subtype = ggv_bin_read16(file, "entry subtype");
+ entry_pos = stream.device()->pos();
+ entry_type = ggv_bin_read16(stream, "entry type");
+ ggv_bin_read16(stream, "entry group");
+ ggv_bin_read16(stream, "entry zoom");
+ entry_subtype = ggv_bin_read16(stream, "entry subtype");
switch (entry_subtype) {
case 0x01:
break;
case 0x10:
// text with 32 bit length field follows
- ggv_bin_read_text32(file, buf, "text len");
+ ggv_bin_read_text32(stream, buf, "text len");
track_name = QString::fromLatin1(buf.constData()).simplified();
break;
default:
switch (entry_type) {
case 0x02:
// text
- ggv_bin_read16(file, "text color");
- ggv_bin_read16(file, "text size");
- ggv_bin_read16(file, "text trans");
- ggv_bin_read16(file, "text font");
- ggv_bin_read16(file, "text angle");
- lon = ggv_bin_read_double(file, "text lon");
- lat = ggv_bin_read_double(file, "text lat");
- ggv_bin_read_text16(file, buf, "text label");
+ ggv_bin_read16(stream, "text color");
+ ggv_bin_read16(stream, "text size");
+ ggv_bin_read16(stream, "text trans");
+ ggv_bin_read16(stream, "text font");
+ ggv_bin_read16(stream, "text angle");
+ lon = ggv_bin_read_double(stream, "text lon");
+ lat = ggv_bin_read_double(stream, "text lat");
+ ggv_bin_read_text16(stream, buf, "text label");
waypt_name = QString::fromLatin1(buf.constData()).simplified();
wpt = new Waypoint;
wpt->longitude = lon;
// line
case 0x04:
// area
- ggv_bin_read16(file, "line color");
- ggv_bin_read16(file, "line width");
- ggv_bin_read16(file, "line type");
- line_points = ggv_bin_read16(file, "line points");
+ ggv_bin_read16(stream, "line color");
+ ggv_bin_read16(stream, "line width");
+ ggv_bin_read16(stream, "line type");
+ line_points = ggv_bin_read16(stream, "line points");
ggv_bin_track = route_head_alloc();
track_add_head(ggv_bin_track);
if (! track_name.isEmpty())
ggv_bin_track->rte_name = track_name;
for (int i = 1; i <= line_points; i++) {
- lon = ggv_bin_read_double(file, "line lon");
- lat = ggv_bin_read_double(file, "line lat");
+ lon = ggv_bin_read_double(stream, "line lon");
+ lat = ggv_bin_read_double(stream, "line lat");
wpt = new Waypoint;
wpt->longitude = lon;
wpt->latitude = lat;
// circle
case 0x07:
// triangle
- ggv_bin_read16(file, "geom color");
- ggv_bin_read16(file, "geom prop1");
- ggv_bin_read16(file, "geom prop2");
- ggv_bin_read16(file, "geom angle");
- ggv_bin_read16(file, "geom stroke");
- ggv_bin_read16(file, "geom area");
- ggv_bin_read_double(file, "geom lon");
- ggv_bin_read_double(file, "geom lat");
+ ggv_bin_read16(stream, "geom color");
+ ggv_bin_read16(stream, "geom prop1");
+ ggv_bin_read16(stream, "geom prop2");
+ ggv_bin_read16(stream, "geom angle");
+ ggv_bin_read16(stream, "geom stroke");
+ ggv_bin_read16(stream, "geom area");
+ ggv_bin_read_double(stream, "geom lon");
+ ggv_bin_read_double(stream, "geom lat");
break;
case 0x09:
- ggv_bin_read16(file, "bmp color");
- ggv_bin_read16(file, "bmp prop1");
- ggv_bin_read16(file, "bmp prop2");
- ggv_bin_read16(file, "bmp prop3");
- ggv_bin_read_double(file, "bmp lon");
- ggv_bin_read_double(file, "bmp lat");
- ggv_bin_read_text32(file, buf, "bmp data");
+ ggv_bin_read16(stream, "bmp color");
+ ggv_bin_read16(stream, "bmp prop1");
+ ggv_bin_read16(stream, "bmp prop2");
+ ggv_bin_read16(stream, "bmp prop3");
+ ggv_bin_read_double(stream, "bmp lon");
+ ggv_bin_read_double(stream, "bmp lat");
+ ggv_bin_read_text32(stream, buf, "bmp data");
break;
default:
fatal(MYNAME ": Unknown entry type (0x%hx, pos=0x%llx) \n", entry_type, entry_pos);
***************************************************************************/
static void
-ggv_bin_read_v34_header(QFile& file, quint32& number_labels, quint32 &number_records)
+ggv_bin_read_v34_header(QDataStream& stream, quint32& number_labels, quint32 &number_records)
{
QByteArray buf;
quint16 header_len;
- ggv_bin_read_bytes(file, buf, 8, "unknown");
- number_labels = ggv_bin_read32(file, "num labels");
- number_records = ggv_bin_read32(file, "num records");
- ggv_bin_read_text16(file, buf, "text label");
- ggv_bin_read16(file, "unknown");
- ggv_bin_read16(file, "unknown");
+ ggv_bin_read_bytes(stream, buf, 8, "unknown");
+ number_labels = ggv_bin_read32(stream, "num labels");
+ number_records = ggv_bin_read32(stream, "num records");
+ ggv_bin_read_text16(stream, buf, "text label");
+ ggv_bin_read16(stream, "unknown");
+ ggv_bin_read16(stream, "unknown");
// 8 bytes ending with 1E 00, contains len of header block
- ggv_bin_read16(file, "unknown");
- header_len = ggv_bin_read16(file, "header len");
- ggv_bin_read16(file, "unknown");
- ggv_bin_read16(file, "unknown");
+ ggv_bin_read16(stream, "unknown");
+ header_len = ggv_bin_read16(stream, "header len");
+ ggv_bin_read16(stream, "unknown");
+ ggv_bin_read16(stream, "unknown");
if (header_len > 0) {
- ggv_bin_read_bytes(file, buf, header_len, "map name");
+ ggv_bin_read_bytes(stream, buf, header_len, "map name");
buf.remove(0,4);
buf.append('\0');
if (global_opts.debug_level > 1)
}
static void
-ggv_bin_read_v34_label(QFile& file)
+ggv_bin_read_v34_label(QDataStream& stream)
{
QByteArray buf;
if (global_opts.debug_level > 1)
- qDebug("------------------------------------ 0x%llx", file.pos());
- ggv_bin_read_bytes(file, buf, 0x08, "label header");
- ggv_bin_read_bytes(file, buf, 0x14, "label number");
- ggv_bin_read_text16(file, buf, "label text");
- ggv_bin_read16(file, "label flag1");
- ggv_bin_read16(file, "label flag2");
+ qDebug("------------------------------------ 0x%llx", stream.device()->pos());
+ ggv_bin_read_bytes(stream, buf, 0x08, "label header");
+ ggv_bin_read_bytes(stream, buf, 0x14, "label number");
+ ggv_bin_read_text16(stream, buf, "label text");
+ ggv_bin_read16(stream, "label flag1");
+ ggv_bin_read16(stream, "label flag2");
}
static QString
-ggv_bin_read_v34_common(QFile& file)
+ggv_bin_read_v34_common(QDataStream& stream)
{
QByteArray buf;
QString res;
quint16 type1;
quint16 type2;
- ggv_bin_read16(file, "entry group");
- ggv_bin_read16(file, "entry prop2");
- ggv_bin_read16(file, "entry prop3");
- ggv_bin_read16(file, "entry prop4");
- ggv_bin_read16(file, "entry prop5");
- ggv_bin_read16(file, "entry prop6");
- ggv_bin_read16(file, "entry prop7");
- ggv_bin_read16(file, "entry prop8");
- ggv_bin_read16(file, "entry zoom");
- ggv_bin_read16(file, "entry prop10");
- ggv_bin_read_text16(file, buf, "entry txt");
+ ggv_bin_read16(stream, "entry group");
+ ggv_bin_read16(stream, "entry prop2");
+ ggv_bin_read16(stream, "entry prop3");
+ ggv_bin_read16(stream, "entry prop4");
+ ggv_bin_read16(stream, "entry prop5");
+ ggv_bin_read16(stream, "entry prop6");
+ ggv_bin_read16(stream, "entry prop7");
+ ggv_bin_read16(stream, "entry prop8");
+ ggv_bin_read16(stream, "entry zoom");
+ ggv_bin_read16(stream, "entry prop10");
+ ggv_bin_read_text16(stream, buf, "entry txt");
res = QString::fromLatin1(buf.constData()).simplified();
- type1 = ggv_bin_read16(file, "entry type1");
+ type1 = ggv_bin_read16(stream, "entry type1");
if (type1 != 1) {
- ggv_bin_read_text32(file, buf, "entry object");
+ ggv_bin_read_text32(stream, buf, "entry object");
}
- type2 = ggv_bin_read16(file, "entry type2");
+ type2 = ggv_bin_read16(stream, "entry type2");
if (type2 != 1) {
- ggv_bin_read_text32(file, buf, "entry object");
+ ggv_bin_read_text32(stream, buf, "entry object");
}
return res;
}
static void
-ggv_bin_read_v34_record(QFile& file)
+ggv_bin_read_v34_record(QDataStream& stream)
{
QByteArray buf;
QString label;
double lon, lat;
if (global_opts.debug_level > 1)
- qDebug("------------------------------------ 0x%llx", file.pos());
+ qDebug("------------------------------------ 0x%llx", stream.device()->pos());
- entry_type = ggv_bin_read16(file, "entry type");
- label = ggv_bin_read_v34_common(file);
+ entry_type = ggv_bin_read16(stream, "entry type");
+ label = ggv_bin_read_v34_common(stream);
switch (entry_type) {
case 0x02:
// text
- ggv_bin_read16(file, "text prop1");
- ggv_bin_read32(file, "text prop2");
- ggv_bin_read16(file, "text prop3");
- ggv_bin_read32(file, "text prop4");
- ggv_bin_read16(file, "text ltype");
- ggv_bin_read16(file, "text angle");
- ggv_bin_read16(file, "text size");
- ggv_bin_read16(file, "text area");
- lon = ggv_bin_read_double(file, "text lon");
- lat = ggv_bin_read_double(file, "text lat");
- ggv_bin_read_double(file, "text unk");
- ggv_bin_read_text16(file, buf, "text label");
+ ggv_bin_read16(stream, "text prop1");
+ ggv_bin_read32(stream, "text prop2");
+ ggv_bin_read16(stream, "text prop3");
+ ggv_bin_read32(stream, "text prop4");
+ ggv_bin_read16(stream, "text ltype");
+ ggv_bin_read16(stream, "text angle");
+ ggv_bin_read16(stream, "text size");
+ ggv_bin_read16(stream, "text area");
+ lon = ggv_bin_read_double(stream, "text lon");
+ lat = ggv_bin_read_double(stream, "text lat");
+ ggv_bin_read_double(stream, "text unk");
+ ggv_bin_read_text16(stream, buf, "text label");
wpt = new Waypoint;
wpt->longitude = lon;
wpt->latitude = lat;
if (! label.isEmpty())
ggv_bin_track->rte_name = label;
- ggv_bin_read16(file, "line prop1");
- ggv_bin_read32(file, "line prop2");
- ggv_bin_read16(file, "line prop3");
- ggv_bin_read32(file, "line color");
- ggv_bin_read16(file, "line size");
- ggv_bin_read16(file, "line stroke");
- line_points = ggv_bin_read16(file, "line points");
+ ggv_bin_read16(stream, "line prop1");
+ ggv_bin_read32(stream, "line prop2");
+ ggv_bin_read16(stream, "line prop3");
+ ggv_bin_read32(stream, "line color");
+ ggv_bin_read16(stream, "line size");
+ ggv_bin_read16(stream, "line stroke");
+ line_points = ggv_bin_read16(stream, "line points");
if (entry_type == 0x04) {
// found in example.ovl generated by Geogrid-Viewer 1.0
- ggv_bin_read16(file, "line pad");
+ ggv_bin_read16(stream, "line pad");
}
for (int i=1; i <= line_points; i++) {
- lon = ggv_bin_read_double(file, "line lon");
- lat = ggv_bin_read_double(file, "line lat");
- ggv_bin_read_double(file, "line unk");
+ lon = ggv_bin_read_double(stream, "line lon");
+ lat = ggv_bin_read_double(stream, "line lat");
+ ggv_bin_read_double(stream, "line unk");
wpt = new Waypoint;
wpt->longitude = lon;
wpt->latitude = lat;
case 0x06:
case 0x07:
// circle
- ggv_bin_read16(file, "circle prop1");
- ggv_bin_read32(file, "circle prop2");
- ggv_bin_read16(file, "circle prop3");
- ggv_bin_read32(file, "circle color");
- ggv_bin_read32(file, "circle prop5");
- ggv_bin_read32(file, "circle prop6");
- ggv_bin_read16(file, "circle ltype");
- ggv_bin_read16(file, "circle angle");
- ggv_bin_read16(file, "circle size");
- ggv_bin_read16(file, "circle area");
- ggv_bin_read_double(file, "circle lon");
- ggv_bin_read_double(file, "circle lat");
- ggv_bin_read_double(file, "circle unk");
+ ggv_bin_read16(stream, "circle prop1");
+ ggv_bin_read32(stream, "circle prop2");
+ ggv_bin_read16(stream, "circle prop3");
+ ggv_bin_read32(stream, "circle color");
+ ggv_bin_read32(stream, "circle prop5");
+ ggv_bin_read32(stream, "circle prop6");
+ ggv_bin_read16(stream, "circle ltype");
+ ggv_bin_read16(stream, "circle angle");
+ ggv_bin_read16(stream, "circle size");
+ ggv_bin_read16(stream, "circle area");
+ ggv_bin_read_double(stream, "circle lon");
+ ggv_bin_read_double(stream, "circle lat");
+ ggv_bin_read_double(stream, "circle unk");
break;
case 0x09:
// bmp
- ggv_bin_read16(file, "bmp prop1");
- ggv_bin_read32(file, "bmp prop2");
- ggv_bin_read16(file, "bmp prop3");
- ggv_bin_read32(file, "bmp prop4");
- ggv_bin_read32(file, "bmp prop5");
- ggv_bin_read32(file, "bmp prop6");
- ggv_bin_read_double(file, "bmp lon");
- ggv_bin_read_double(file, "bmp lat");
- ggv_bin_read_double(file, "bmp unk");
- bmp_len = ggv_bin_read32(file, "bmp len");
- ggv_bin_read16(file, "bmp prop");
- ggv_bin_read_bytes(file, buf, bmp_len, "bmp data");
+ ggv_bin_read16(stream, "bmp prop1");
+ ggv_bin_read32(stream, "bmp prop2");
+ ggv_bin_read16(stream, "bmp prop3");
+ ggv_bin_read32(stream, "bmp prop4");
+ ggv_bin_read32(stream, "bmp prop5");
+ ggv_bin_read32(stream, "bmp prop6");
+ ggv_bin_read_double(stream, "bmp lon");
+ ggv_bin_read_double(stream, "bmp lat");
+ ggv_bin_read_double(stream, "bmp unk");
+ bmp_len = ggv_bin_read32(stream, "bmp len");
+ ggv_bin_read16(stream, "bmp prop");
+ ggv_bin_read_bytes(stream, buf, bmp_len, "bmp data");
break;
default:
fatal(MYNAME ": Unsupported type: %x\n", entry_type);
}
static void
-ggv_bin_read_v34(QFile& file)
+ggv_bin_read_v34(QDataStream& stream)
{
QByteArray buf;
QString track_name;
quint32 label_count;
quint32 record_count;
- while (!file.atEnd()) {
- ggv_bin_read_v34_header(file, label_count, record_count);
+ while (!stream.atEnd()) {
+ ggv_bin_read_v34_header(stream, label_count, record_count);
- if (label_count && !file.atEnd()) {
+ if (label_count && !stream.atEnd()) {
if (global_opts.debug_level > 1)
- qDebug("-----labels------------------------- 0x%llx", file.pos());
+ qDebug("-----labels------------------------- 0x%llx", stream.device()->pos());
for (unsigned int i = 0; i < label_count; i++)
- ggv_bin_read_v34_label(file);
+ ggv_bin_read_v34_label(stream);
}
- if (record_count && !file.atEnd()) {
+ if (record_count && !stream.atEnd()) {
if (global_opts.debug_level > 1)
- qDebug("-----records------------------------ 0x%llx", file.pos());
+ qDebug("-----records------------------------ 0x%llx", stream.device()->pos());
for (unsigned int i = 0; i < record_count; i++)
- ggv_bin_read_v34_record(file);
+ ggv_bin_read_v34_record(stream);
}
- if (!file.atEnd()) {
+ if (!stream.atEnd()) {
if (global_opts.debug_level > 1)
- qDebug("------------------------------------ 0x%llx", file.pos());
+ qDebug("------------------------------------ 0x%llx", stream.device()->pos());
// we just skip over the next magic bytes without checking they
// contain the correct string. This is consistent with what I
// believe GGV does
- ggv_bin_read_bytes(file, buf, 23, "magicbytes");
+ ggv_bin_read_bytes(stream, buf, 23, "magicbytes");
if (global_opts.debug_level > 1)
qDebug() << "ovl: header = " << buf.constData();
}
}
if (global_opts.debug_level > 1) {
- qDebug("fpos: 0x%llx", file.pos());
- qDebug("size: 0x%llx", file.size());
+ qDebug("fpos: 0x%llx", stream.device()->pos());
+ qDebug("size: 0x%llx", stream.device()->size());
}
}
***************************************************************************/
static void
-ggv_bin_read_file(QFile& file)
+ggv_bin_read_file(QDataStream& stream)
{
QByteArray buf;
- ggv_bin_read_bytes(file, buf, 0x17, "magic");
+ ggv_bin_read_bytes(stream, buf, 0x17, "magic");
buf[23] = 0;
if (global_opts.debug_level > 1) {
qDebug() << "ovl: header =" << buf.constData();
}
if (buf.startsWith("DOMGVCRD Ovlfile V2.0")) {
- ggv_bin_read_v2(file);
+ ggv_bin_read_v2(stream);
} else if (buf.startsWith("DOMGVCRD Ovlfile V3.0")) {
- ggv_bin_read_v34(file);
+ ggv_bin_read_v34(stream);
} else if (buf.startsWith("DOMGVCRD Ovlfile V4.0")) {
- ggv_bin_read_v34(file);
+ ggv_bin_read_v34(stream);
} else {
fatal(MYNAME ": Unsupported file format\n");
}
fatal(MYNAME ": Error opening file %s\n", read_fname.toStdString().c_str());
}
- ggv_bin_read_file(file);
+ QDataStream stream(&file);
+ stream.setFloatingPointPrecision(QDataStream::DoublePrecision);
+ stream.setByteOrder(QDataStream::LittleEndian);
+
+ ggv_bin_read_file(stream);
file.close();
}